#include "./res/m.h"


//宏定义服务器(ubuntu)的IP和端口号
#define SERVER_PORT  10000
#define SERVER_IP   "192.168.8.67"
#define CLIENT_PORT  15000
#define CLIENT_IP   "192.168.8.69"

lv_obj_t *win_copy = NULL;//窗口拷贝
int socketfd;
int i = 0;
int ret;
//将灯设备的文件描述符定义成全局变量
int fd;
int iLED = 0;
char LEDbuf[2];
char* rcvbuf_1 = NULL;
char* rcvbuf_2 = NULL;
static char tx_buf[1024];
static char tx0_buf[1024];
char *p = NULL;
char *bool_data = NULL;
char *bll_data = NULL;
lv_obj_t *img = NULL;
extern pthread_t id;
extern char *rcv_buf11;

//pthread_t id;

// void* update_data(void *arg) 
// {
//     printf("%d\n",*(int *)arg);
    
//     socketfd = *(int *)arg;

//     if(i == 0)
//     {         
//         printf("2 socketfd:%d\n",socketfd);
//         i=i+1;
//     } 
         
//     while (1)
//     {
//         memset(tx_buf,0,sizeof(tx_buf));
//        // 通信   
//         sprintf(tx_buf,"%s %s",rcvbuf_1,rcvbuf_2);
//         printf("正在上报数据....\n");       
//         printf("发送的数据:%s\nsize:%d\n",tx_buf,strlen(tx_buf));
        
//         ret = write(socketfd, tx_buf, strlen(tx_buf));
//         if (ret == -1) 
//         {
//             perror("写入数据失败");
//             close(socketfd);
//             socketfd = -1;
//             return NULL;
//         }
    
//         if(ret == 0)
//         {
//             perror("服务器已关闭...即将退出...");
//             close(socketfd);
//             return NULL;
//         }
//         printf("写入的字节数:%d\n",ret);
//         printf("========================数据上报分割线========================\n");
//         sleep(5);
//     }  
// }

// 数据更新定时器
void update_data() 
{   
    // 用于放置只执行一次的代码
    if(i == 0)
    {
        //设置套接字的属性为 非阻塞
        //1.先得到套接字原来的属性变量
        int state = fcntl(socketfd, F_GETFL);
        //2.将这个属性变量 添加 非阻塞属性功能  O_NONBLOCK
        state |= O_NONBLOCK;
        //3.再设置到套接字文件中
        fcntl(socketfd, F_SETFL,state);
        i=1;
    }
                     
        memset(tx_buf,0,sizeof(tx_buf));
        // 通信   
        sprintf(tx_buf,"%s\n%s\n%d", rcvbuf_1, rcvbuf_2, LED_state_flag);
        printf("正在上报数据....\n");       
        printf("发送的数据:%s\nsize:%d\n",tx_buf,strlen(tx_buf));
        
        ret = write(socketfd, tx_buf, strlen(tx_buf));
        if (ret == -1) 
        {
            perror("写入数据失败");
            close(socketfd);
            socketfd = -1;
            return;
        }
    
        if(ret == 0)
        {
            perror("服务器已关闭...即将退出...");
            close(socketfd);
            return;
        }
        printf("写入的字节数:%d\n",ret);
        printf("========================数据上报分割线========================\n");
        
        
    //读取服务器下达的命令
    ret = read(socketfd, tx0_buf, sizeof(tx0_buf));
    if(ret == -1)
    {
        printf("尚未下达命令\n");
    }
    
    else if(ret == 0) 
    {
        printf("服务器已关闭连接\n");
    }
    
    else if(ret > 0)
    {
        printf("服务器下达的命令:%s\n", tx0_buf);
        //p用于阉割数据
	    p = strtok(tx0_buf, ":");
        p = strtok(NULL, ":");
        bool_data = strtok(NULL, "}");
        //printf("bool_data:%s\n",bool_data);
   
        
        // 判断下达的命令为true还是false
        if(strcmp(bool_data,"true") == 0)
        {
            //为true开灯
            if(iLED == 0)
            {
                // 打开文件
                fd = open("/dev/led_drv",O_RDWR);
                if(fd == -1)
                {
                    perror("open");
                    return;
                }
                printf("打开文件成功\n");
                iLED=1;
                
            } 
            // 标志更改
            LED_state_flag = 1;
            LEDbuf[0] = 1;//全部开灯
            LEDbuf[1] = 7; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 8; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 9; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 10; //灯的编号
            int ret = write(fd,LEDbuf,sizeof(LEDbuf));
            if(ret == -1)
            {   
                perror("write error");
                return;
            }         
                     
        }
        
        
        else if(strcmp(bool_data,"false") == 0)
        {
            //为false关灯
            if(iLED == 0)
            {
                // 打开文件
                fd = open("/dev/led_drv",O_RDWR);
                if(fd == -1)
                {
                    perror("open");
                    return;
                }
                printf("打开文件成功\n");
                iLED=1;
                
            } 
            // 标志更改
            LED_state_flag = 0;    
            LEDbuf[0] = 0;//全部关灯
            LEDbuf[1] = 7; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 8; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 9; //灯的编号
            write(fd,LEDbuf,sizeof(LEDbuf));
            LEDbuf[1] = 10; //灯的编号
            int ret = write(fd,LEDbuf,sizeof(LEDbuf));
            if(ret == -1)
            {   
                perror("write error");
                return;
            }         
            
        }
        
        
        else if(strcmp(bool_data,"\"open1\"") == 0)
        {
            // 播放音乐
            printf("正在播放音乐...\n");
            music();
            
        }

        else if(strcmp(bool_data,"\"close1\"") == 0)
        {
            // 关闭音乐
            printf("正在关闭音乐...\n");
            system("killall -9 madplay");
            
        }
        
        else if(strcmp(bool_data,"\"pause1\"") == 0)
        {
            // 暂停音乐
            printf("暂停音乐...\n");
            system("killall -19 madplay");
            
        }
        
        else if(strcmp(bool_data,"\"continue1\"") == 0)
        {
            // 继续播放音乐
            printf("继续播放音乐...\n");
            system("killall -18 madplay");
            
        }
        
        
        else if(strcmp(bool_data,"\"open2\"") == 0)
        {
            // 隐藏主界面
            lv_obj_add_flag(win_copy, LV_OBJ_FLAG_HIDDEN);
            
            // 打开视频
            printf("正在加载擦边视频...\n");
            video();
            
        }
        
        else if(strcmp(bool_data,"\"close2\"") == 0)
        {
            // 关闭视频
            printf("正在关闭擦边视频...\n");
            system("killall -9 mplayer");
            
            // 解除隐藏属性
            lv_obj_clear_flag(win_copy, LV_OBJ_FLAG_HIDDEN); 
            
        }
        
        else if(strcmp(bool_data,"\"pause2\"") == 0)
        {
            // 暂停视频
            printf("暂停擦边视频...\n");
            system("killall -19 mplayer");
            
        }
        
        else if(strcmp(bool_data,"\"continue2\"") == 0)
        {
            // 继续播放视频
            printf("继续播放擦边视频...\n");
            system("killall -18 mplayer");
            
        }
        
        else if(strcmp(bool_data,"\"openpth\"") == 0)
        {
            // 开启线程
            printf("开启线程...\n");
            // 请求开启线程
            //创建线程去闪烁灯
            pthread_create(&id, NULL, &LED_blink1, (void *)rcv_buf11);
            
        } 
        
        else if(strcmp(bool_data,"\"closepth\"") == 0)
        {
            // 关闭线程
            printf("关闭线程...\n");
            // 请求取消线程
            pthread_cancel(id);
            
        }
        
        else if(strcmp(bool_data,"\"do\"") == 0)
        {
            // 隐藏主界面
            lv_obj_add_flag(win_copy, LV_OBJ_FLAG_HIDDEN);
            
            printf("开启所有\n");
            music1(); 
            video1();
        }
        
        else if(strcmp(bool_data,"\"dc\"") == 0)
        {
            printf("关闭所有\n");
            system("killall -9 madplay");
            system("killall -9 mplayer");

            // 解除隐藏属性
            lv_obj_clear_flag(win_copy, LV_OBJ_FLAG_HIDDEN); 
        }
        
    }
       
}


// 数据上报模块
// 开发板是客户端
void data_reporting(lv_obj_t *win, char* rcvbuf1, char* rcvbuf2)
{   
    rcvbuf_1 = rcvbuf1;
    rcvbuf_2 = rcvbuf2;
    win_copy = win;
    
    // 先让开发板的数据可以传给Ubuntu,采用TCP协议
    printf("我是GEC6816,我的端口号:%d,IP号:%s\n",CLIENT_PORT,CLIENT_IP);

    //创建套接字
    socketfd=socket(AF_INET, SOCK_STREAM, 0);
    if(socketfd == -1)
    {
        perror("socket error");
        return;
    }

    //设置端口号复用
    //当你结束程序 ，立马又运行程序的时候会报IP地址被占用，实际上是刚才退出的那个程序端口号还被占用着
    //系统必须要经过一段时间之后，才会将刚才结束的那个程序的端口号释放出来
    int optval = 1;
    setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval));

    //绑定自己的IP地址和端口号
    struct sockaddr_in addr;//新版结构体
    //选择IPV4协议
    addr.sin_family = AF_INET;
    //绑定自己的端口号
    addr.sin_port = htons(CLIENT_PORT);//该函数将本地端口号转化为网络字节序端口号
    //绑定自己的IP地址
    addr.sin_addr.s_addr = inet_addr(CLIENT_IP);//该函数将本地IP转化为网络字节序IP
    //绑定套接字
    ret = bind(socketfd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in));
    if(ret == -1)
    {
        perror("bind error");
        return;
    }


    //连接服务器
    //绑定对方的IP地址和端口号
    struct sockaddr_in server_addr;//新版结构体
    //选择IPV4协议
    server_addr.sin_family = AF_INET;
    //绑定对方的端口号
    server_addr.sin_port = htons(SERVER_PORT);
    //绑定对方的IP地址
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    //连接服务器
    ret = connect(socketfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if(ret == -1)
    {
        perror("connect error");
        return;
    }

    // 创建定时器，每2秒更新一次数据
    lv_timer_create(update_data, 2000, NULL);
    
    // 用线程来上报数据，有点不太行
    //pthread_create(&id, NULL, update_data, (void *)&socketfd);
    //pthread_join(id, NULL);
    
    // 关闭套接字
    // close(socketfd);

    return;
}
